package com.quanquan.parking.ketop.service;

import DTO.PageDTO;
import DTO.user.UserDTO;
import DTO.user.UserInfoDTO;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.quanquan.parking.configBeans.RabbitSender;
import com.quanquan.parking.ketop.api.BaseApi;
import com.quanquan.parking.ketop.dto.IdDTO;
import com.quanquan.parking.ketop.dto.KetopParkingRecordDTO;
import com.quanquan.parking.ketop.dto.PaymentRechargeDTO;
import com.quanquan.parking.ketop.entity.ParkingRecord;
import com.quanquan.parking.ketop.entity.UserCarKetop;
import com.quanquan.parking.ketop.entity.UserDisCount;
import com.quanquan.parking.ketop.entity.params.ParkingConfig;
import com.quanquan.parking.ketop.entity.params.request.PayParkingFeeRequest;
import com.quanquan.parking.ketop.entity.params.request.QueryParkingFeeRequest;
import com.quanquan.parking.ketop.entity.params.request.UserCarKetopRequest;
import com.quanquan.parking.ketop.entity.params.response.FreeDetail;
import com.quanquan.parking.ketop.entity.params.response.ParkingFeeResponse;
import com.quanquan.parking.ketop.exception.EncodeException;
import com.quanquan.parking.ketop.exception.RequestException;
import com.quanquan.parking.ketop.repository.ParkingRecordRepository;
import com.quanquan.parking.ketop.repository.UserCarKetopRepository;
import com.quanquan.parking.ketop.request.UserRequestBody;
import com.quanquan.parking.request.PayNotifyRequest;
import commond.IntegralOutPut;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.core.internal.Function;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import utils.DateUtils;
import utils.Request;
import utils.StringUtil;
import utils.UUIDGenerator;

import javax.persistence.criteria.Predicate;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @ClassName:ParkingService
 * @Description:TODO
 * @Author:xiongjunbao
 * @Date:2019/4/3 13:23
 * @Version 1.0
 */
@Service
public class KetopParkingService {

    private final ParkingConfig config;
    private final UserCarKetopRepository userCarKetopRepository;
    private final ParkingRecordRepository parkingRecordRepository;
    private final RestTemplate restTemplate;
    private final UserDisCountService userDisCountService;
    private final RabbitSender rabbitSender;

    @Autowired
    public KetopParkingService(ParkingConfig config, UserCarKetopRepository userCarKetopRepository, ParkingRecordRepository parkingRecordRepository, RestTemplate restTemplate, UserDisCountService userDisCountService, RabbitSender rabbitSender) {
        this.config = config;
        this.userCarKetopRepository = userCarKetopRepository;
        this.parkingRecordRepository = parkingRecordRepository;
        this.restTemplate = restTemplate;
        this.userDisCountService = userDisCountService;
        this.rabbitSender = rabbitSender;
    }

    @Value("${module-url.userUrl}")
    private String userUrl;

    /**
     * 用户绑定车牌
     *
     * @param request
     * @return
     */
    public boolean bindUserCar(UserCarKetopRequest request) {
        List<UserCarKetop> userCarKetops = userCarKetopRepository.findByUserIdAndPlateNum(request.getUserId(), request.getPlateNum());
        if (userCarKetops.size() <= 0) {
            UserCarKetop userCarKetop = new UserCarKetop();
            BeanUtil.copyProperties(request, userCarKetop, true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            userCarKetop.setId(UUIDGenerator.getUUID());
            userCarKetop.setCreateTime(DateUtils.currentDate());
            userCarKetop.setUpdateTime(DateUtils.currentDate());
            userCarKetop.setStatus(0);
            userCarKetopRepository.saveAndFlush(userCarKetop);
        } else {
            UserCarKetop userCarKetop = userCarKetops.get(0);
            //如果删除，重新绑定
            if (userCarKetop.getStatus() == 1) {
                userCarKetop.setUpdateTime(DateUtils.currentDate());
                userCarKetop.setStatus(0);
                userCarKetopRepository.saveAndFlush(userCarKetop);
            }
        }
        return true;
    }

    /**
     * 用户解绑车牌
     *
     * @param request
     * @return
     */
    public boolean deleteUserCar(UserCarKetopRequest request) {
        List<UserCarKetop> userCarKetops = userCarKetopRepository.findByUserIdAndPlateNum(request.getUserId(), request.getPlateNum());
        UserCarKetop userCarKetop = userCarKetops.get(0);
        //如果未找到
        if (userCarKetop == null) {
            return false;
        } else {
            //如果已解绑
            if (userCarKetop.getStatus() == 1) {
                return false;
            } else {
                //未解绑，给用户解绑车牌
                userCarKetop.setUpdateTime(DateUtils.currentDate());
                userCarKetop.setStatus(1);
                userCarKetopRepository.saveAndFlush(userCarKetop);
                return true;
            }
        }
    }

    /**
     * 用户绑定的车牌列表
     *
     * @param request
     * @return
     */
    public List<Object> findByUserId(UserCarKetopRequest request) {
        List<Object> objectList = new LinkedList<>();
        //分页查询
        Integer page = request.getPage() == null ? 0 : request.getPage();
        Integer size = request.getSize() == null ? 10 : request.getSize();
        List<UserCarKetop> userCarKetops = userCarKetopRepository.findByUserId(request.getUserId(), page * size, size);
        for (UserCarKetop userCarKetop : userCarKetops) {
            Map<String, Object> map = new HashMap<>();
            map.put("plateNum", userCarKetop.getPlateNum());
            objectList.add(map);
        }
        return objectList;
    }

    /**
     * 查询停车费用并生成订单
     *
     * @return
     * @see [类、类#方法、类#成员]
     */
    public List<Object> queryParkingFee(UserCarKetopRequest userCarKetopRequest) {
        List<Object> objectList = new LinkedList<>();
        bindUserCar(userCarKetopRequest);
        String apiName = "pay/GetParkingPaymentInfo";
        QueryParkingFeeRequest request = new QueryParkingFeeRequest();
        request.setPlateNo(userCarKetopRequest.getPlateNum());
        String result;
        try {
            result = BaseApi.doApi(request, apiName);
            JSONArray list = JSONObject.parseArray(result);
            for (int i = 0; i < list.size(); i++) {
                ParkingFeeResponse data = list.getObject(i, ParkingFeeResponse.class);
                if (data.getPayable() <= 0) {
                    continue;
                }
                Map<String, Object> map = new HashMap<>();
                map.put("imgName", data.getImgName());
                map.put("entryTime", data.getEntryTime());
                map.put("orderNo", data.getOrderNo());
                double fee = data.getPayable().doubleValue();
                DecimalFormat df = new DecimalFormat("0.00");
                String str = df.format(fee / 100);
                map.put("payable", str);
                map.put("payTime", data.getPayTime());
                map.put("delayTime", data.getDelayTime());
                map.put("elapsedTime", data.getElapsedTime());
                objectList.add(map);
            }
            return objectList;
        } catch (RequestException | EncodeException e) {
            e.printStackTrace();
        }
        return null;
    }
//    积分抵扣
//    totalFreeFee = (userCarKetopRequest.getIntegral() / 20) * 50;


    /**
     * 查询停车费用(保存订单)
     *
     * @return
     * @see [类、类#方法、类#成员]
     */
    public List<ParkingRecord> queryParkingFeeAndCreateOrder(UserCarKetopRequest userCarKetopRequest) {
        String apiName = "pay/GetParkingPaymentInfo";
        QueryParkingFeeRequest request = new QueryParkingFeeRequest();
        request.setPlateNo(userCarKetopRequest.getPlateNum());
        String result;
        List<ParkingRecord> parkingRecords = new LinkedList<>();
        try {
            result = BaseApi.doApi(request, apiName);
            JSONArray list = JSONObject.parseArray(result);
            for (int i = 0; i < list.size(); i++) {
                ParkingFeeResponse data = list.getObject(i, ParkingFeeResponse.class);
                ParkingRecord parkingRecord = new ParkingRecord();
                parkingRecord.setId(UUIDGenerator.getUUID());
                parkingRecord.setCreateTime(DateUtils.currentDate());
                parkingRecord.setUpdateTime(DateUtils.currentDate());
                parkingRecord.setOrderNo(data.getOrderNo());
                parkingRecord.setInTime(data.getEntryTime());
                parkingRecord.setPayTime(data.getPayTime());
                parkingRecord.setImgName(data.getImgName());
                parkingRecord.setDisType(userCarKetopRequest.getDisType());
                if (userCarKetopRequest.getDisType() == 1) {
                    // 积分支付
                    parkingRecord.setIntegral(userCarKetopRequest.getIntegral());
                } else if (userCarKetopRequest.getDisType() == 2) {
                    parkingRecord.setIntegral(0);
                    // 优惠券支付
                    parkingRecord.setCouponCode(userCarKetopRequest.getCouponCode());
                    parkingRecord.setCouponName(userCarKetopRequest.getCouponName());
                } else if (userCarKetopRequest.getDisType() == 3) {
                    // 会员支付
                    parkingRecord.setIntegral(0);
                } else {
                    // 现金支付
                    parkingRecord.setIntegral(0);
                }
                //抵扣金额
                if (userCarKetopRequest.getTotalFreeFee() == null || userCarKetopRequest.getTotalFreeFee() <= 0) {
                    parkingRecord.setIntegral(0);
                } else {
                    parkingRecord.setTotalFreeFee(userCarKetopRequest.getTotalFreeFee());
                }
                parkingRecord.setTotalFee(data.getPayable());
                parkingRecord.setDelayTime(data.getDelayTime());
                parkingRecord.setUserId(userCarKetopRequest.getUserId());
                parkingRecord.setPlateNum(userCarKetopRequest.getPlateNum());
                parkingRecord.setStatus(0);
                if (userCarKetopRequest.getType() == 1) {
                    parkingRecord = parkingRecordRepository.saveAndFlush(parkingRecord);
                }
                parkingRecords.add(parkingRecord);
            }
            return parkingRecords;
        } catch (RequestException | EncodeException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 更新停车账单（当费用为0的时候调用）
     *
     * @return
     * @see [类、类#方法、类#成员]
     */
    public boolean updateOrder(PayParkingFeeRequest request) {
        //拿到科拓的返回值，更新我们的停车支付状态为已支付
        List<ParkingRecord> parkingRecords = parkingRecordRepository.findByOrderNo(request.getOrderNo());
        if (parkingRecords.size() > 0) {
            ParkingRecord parkingRecord = parkingRecords.get(0);
            parkingRecord.setUpdateTime(DateUtils.currentDate());
            parkingRecord.setStatus(1);
            parkingRecordRepository.saveAndFlush(parkingRecord);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 更新停车账单（扣减积分失败的时候调用）
     *
     * @return
     * @see [类、类#方法、类#成员]
     */
    public boolean updateOrderFail(PayParkingFeeRequest request) {
        //拿到科拓的返回值，更新我们的停车支付状态为已支付
        List<ParkingRecord> parkingRecords = parkingRecordRepository.findByOrderNo(request.getOrderNo());
        if (parkingRecords.size() > 0) {
            ParkingRecord parkingRecord = parkingRecords.get(0);
            parkingRecord.setUpdateTime(DateUtils.currentDate());
            parkingRecord.setStatus(-1);
            parkingRecordRepository.saveAndFlush(parkingRecord);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 账单减免计费接口
     *
     * @return
     * @see [类、类#方法、类#成员]
     */
    public PaymentRechargeDTO getPaymentRecharge(PayParkingFeeRequest request) {
        UserCarKetopRequest userCarKetopRequest = new UserCarKetopRequest();
        userCarKetopRequest.setType(request.getType());
        userCarKetopRequest.setPlateNum(request.getPlateNum());
        userCarKetopRequest.setUserId(request.getUserId());
        userCarKetopRequest.setDisType(request.getDisType());
        userCarKetopRequest.setCouponCode(request.getCouponCode());
        userCarKetopRequest.setCouponName(request.getCouponName());
        List<ParkingRecord> parkingRecords = queryParkingFeeAndCreateOrder(userCarKetopRequest);
        if (parkingRecords.size() <= 0) {
            return null;
        }
        String apiName = "pay/GetPaymentRecharge";
        String result;
        try {
            ParkingRecord parkingRecord = parkingRecords.get(0);
            PaymentRechargeDTO data = new PaymentRechargeDTO();
            request.setOrderNo(parkingRecord.getOrderNo());
            result = BaseApi.doApi(request, apiName);
            System.out.println(result);
            JSONArray list = JSONObject.parseArray(result);
            if (list.size() > 0) {
                JSONObject jsonObject = list.getJSONObject(0);
                if (jsonObject.containsKey("payable")) {
                    data.setOrderNo(jsonObject.getString("orderNo"));
                    data.setPayable(jsonObject.getInteger("payable"));
                    if (request.getType() == 1) {
                        parkingRecord.setFee(data.getPayable());
                        parkingRecordRepository.saveAndFlush(parkingRecord);
                    }
                    return data;
                }
            } else {
                return null;
            }
        } catch (RequestException | EncodeException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 同步停车账单
     *
     * @return
     * @see [类、类#方法、类#成员]
     */
    public ParkingRecord payParkingFee(PayParkingFeeRequest request) {
        PaymentRechargeDTO paymentRecharge = getPaymentRecharge(request);
        Integer payType = 24;
        Integer payMethod = 4;
        String apiName = "pay/PayParkingFee";
        request.setPayType(payType);
        request.setPayMethod(payMethod);
        request.setDiscount(0);
        String result;
        try {
            result = BaseApi.doApi(request, apiName);
            JSONObject jo = JSONObject.parseObject(result);
            if (jo.containsKey("parkingTime")) {
                //拿到科拓的返回值，更新我们的停车支付状态为已支付
                List<ParkingRecord> parkingRecords = parkingRecordRepository.findByOrderNo(request.getOrderNo());
                if (parkingRecords.size() > 0) {
                    ParkingRecord parkingRecord = parkingRecords.get(0);
                    // 塞入优免费用（总费用-剩余支付费用）
                    parkingRecord.setTotalFreeFee(parkingRecord.getTotalFee() - paymentRecharge.getPayable());
                    parkingRecord.setParkingTime(jo.getInteger("parkingTime"));
                    parkingRecord.setTransactionId(request.getTransactionId());
                    parkingRecord.setStatus(1);
                    parkingRecord.setUpdateTime(DateUtils.currentDate());
                    parkingRecordRepository.saveAndFlush(parkingRecord);
                    if (paymentRecharge.getPayable()<=0){
                        //发送任务队列，完成签到任务
                        Map<String, Object> properties = new HashMap<>();
                        properties.put("userId", parkingRecord.getUserId());
                        properties.put("taskType", "parking");
                        //将计算结果放到MQ队列去补充明细的余额
                        String msg = "补全积分明细余额";
                        String exchange = "task.exchange";
                        String routingKey = "task.sign";
                        rabbitSender.sendMessageToMQ(msg, properties, exchange, routingKey);
                    }
                    return parkingRecord;
                } else {
                    return null;
                }
            }
        } catch (RequestException | EncodeException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 查找停车订单
     *
     * @param request
     * @return
     */
    public List<ParkingRecord> queryByParkingOrderNum(PayParkingFeeRequest request) {
        return parkingRecordRepository.findByOrderNo(request.getOrderNo());
    }

    /**
     * 账单减免计费接口(点击使用积分，账单减免计费接口)
     *
     * @param request
     * @return
     */
    public Map<String, Object> useIntegral(PayParkingFeeRequest request) {
        Map<String, Object> map = new HashMap<>();
        UserRequestBody userRequestBody = new UserRequestBody();
        //通过openid查找用户
        userRequestBody.setUserId(request.getUserId());
        String postJson1 = Request.postJson(userUrl + "/user/qurey_by_user_id", userRequestBody);
        JSONObject jsonObject1 = JSON.parseObject(postJson1);
        if (null == jsonObject1) {
            map.put("msg", "用户系统异常");
            return map;
        }
        Integer resCode1 = jsonObject1.getInteger("resCode");
        UserDTO data1;
        if (0 == resCode1) {
            data1 = jsonObject1.getJSONObject("data").toJavaObject(UserDTO.class);
            Integer integral = data1.getIntegral();
            if (integral < request.getIntegral()) {
                map.put("msg", "用户积分不足");
                return map;
            }
        } else {
            map.put("msg", "未查询到该用户");
            return map;
        }
        Date date = new Date();
        System.out.println(date);
        double v = request.getIntegral().doubleValue() / 20 * 50;
        Integer money = new Double(v).intValue();
        //根据停车发放券状态判断是否核销
        // 配置金额抵扣
        request.setDisType(1);
        request.setType(0);
        request.setFreeMoney(money);
        request.setFreeTime(0);
        //封装抵扣细节
        FreeDetail freeDetail = new FreeDetail();
        freeDetail.setCode(request.getUserId());
        freeDetail.setMoney(money);
        freeDetail.setTime(0);
        freeDetail.setType(0);
        List<FreeDetail> freeDetails = new LinkedList<>();
        freeDetails.add(freeDetail);
        request.setFreeDetail(freeDetails);

        PaymentRechargeDTO paymentRechargeDTO = getPaymentRecharge(request);
        map.put("msg", "SUCCESS");
        map.put("orderNo", paymentRechargeDTO.getOrderNo());
        DecimalFormat df = new DecimalFormat("0.00");
        double fee = paymentRechargeDTO.getPayable().doubleValue();
        String feeYuan = df.format(fee / 100);
        map.put("payable", feeYuan);
        return map;

    }

    /**
     * 确认使用积分
     *
     * @param request
     * @return
     */
    public String sureUseIntegral(PayParkingFeeRequest request) {
        Date date = new Date();
        System.out.println(date);
        double v = request.getIntegral().doubleValue() / 20 * 50;
        Integer money = new Double(v).intValue();
        UserRequestBody userRequestBody = new UserRequestBody();
        //通过openid查找用户
        userRequestBody.setUserId(request.getUserId());
        String postJson1 = Request.postJson(userUrl + "/user/qurey_by_user_id", userRequestBody);
        JSONObject jsonObject1 = JSON.parseObject(postJson1);
        if (null == jsonObject1) {
            return "用户系统异常";
        }
        Integer resCode1 = jsonObject1.getInteger("resCode");
        UserDTO data1;
        if (0 == resCode1) {
            data1 = jsonObject1.getJSONObject("data").toJavaObject(UserDTO.class);
            Integer integral = data1.getIntegral();
            if (integral < request.getIntegral()) {
                return "用户积分不足";
            }
        } else {
            return "未查询到该用户";
        }
        IntegralOutPut integralOutPut = new IntegralOutPut();
        integralOutPut.setIntegralPoint(request.getIntegral().toString());
        Long orderNum = System.currentTimeMillis();
        integralOutPut.setOrderNum(orderNum.toString());
        integralOutPut.setUserId(request.getUserId());
        integralOutPut.setSource("积分抵扣停车费");
        integralOutPut.setTradeAction(1);
        integralOutPut.setForeignKeyId(request.getUserId());
        integralOutPut.setRemark("水游城小程序停车 - " + request.getPlateNum());
        DecimalFormat df = new DecimalFormat("0.00");
        String str = df.format(money / 100);
        integralOutPut.setTradingContent("停车抵扣金额:" + str + "元");
        integralOutPut.setConsumeType("parking");
        String postJson3 = Request.postJson(userUrl + "/integral_details/check_Integral_deduct", integralOutPut);
        JSONObject jsonObjec3 = JSON.parseObject(postJson3);
        if (null == jsonObjec3) {
            return "积分系统异常";
        } else {
            if (jsonObjec3.containsKey("resCode") && jsonObjec3.getInteger("resCode") == 0) {
                //根据停车发放券状态判断是否核销
                // 配置金额抵扣
                request.setDisType(1);
                request.setType(1);
                request.setFreeMoney(money);
                request.setFreeTime(0);
                //封装抵扣细节
                FreeDetail freeDetail = new FreeDetail();
                freeDetail.setCode(request.getUserId());
                freeDetail.setMoney(money);
                freeDetail.setTime(0);
                freeDetail.setType(0);
                List<FreeDetail> freeDetails = new LinkedList<>();
                freeDetails.add(freeDetail);
                request.setFreeDetail(freeDetails);
                ParkingRecord parkingRecord = payParkingFee(request);
                if (parkingRecord != null) {
                    return "SUCCESS";
                } else {
                    return "抵扣失败";
                }
            } else {
                return "积分扣减失败";
            }
        }


    }


    /**
     * 查找停车订单
     *
     * @param request
     * @return
     */
    public List<ParkingRecord> findByUserIdAndStatus(UserCarKetopRequest request) {
        String userId = request.getUserId();
        Integer page = request.getPage() == null ? 0 : request.getPage();
        Integer size = request.getSize() == null ? 30 : request.getSize();
        return parkingRecordRepository.findByUserIdAndStatus(userId, page * size, size);
    }

    /**
     * 停车缴费记录
     *
     * @param requestBody
     * @return
     */
    public PageDTO<KetopParkingRecordDTO> parkingRecord(PayNotifyRequest requestBody) {
        //分页
        Integer page = null == requestBody.getPage() ? 0 : requestBody.getPage();
        Integer size = null == requestBody.getSize() ? 10 : requestBody.getSize();
        //优惠券创建时间区间
        String fromDate = requestBody.getFromDate();
        String toDate = requestBody.getToDate();
        //排序状态
        Sort sort = new Sort(Sort.Direction.DESC, "payTime");
        //搜索关键词
        String keyword = requestBody.getKeyword();
        Pageable pageable = PageRequest.of(page, size, sort);
        Page<ParkingRecord> paged = parkingRecordRepository.findAll((Specification<ParkingRecord>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtil.isNotEmpty(fromDate)) {
                Date startOfDay = DateUtils.getStartOfDay(DateUtils.strToDate(fromDate, DateUtils.DATE));
                predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("payTime").as(Date.class), startOfDay));
            }
            if (StringUtil.isNotEmpty(toDate)) {
                Date endOfDay = DateUtils.getEndOfDay(DateUtils.strToDate(toDate, DateUtils.DATE));
                predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("payTime").as(Date.class), endOfDay));
            }
            if (StringUtil.isNotEmpty(keyword)) {
                if (StringUtil.isNotEmpty(keyword)) {
                    IdDTO idDTO = new IdDTO();
                    idDTO.setKeyWord(keyword);
                    UserInfoDTO userInfoDTO = restTemplate.postForObject("http://QUANQUAN-USER/user/query_keyword", idDTO, UserInfoDTO.class);
                    if (userInfoDTO != null) {
                        List<UserDTO> users = userInfoDTO.getUserDTOS();
                        if (users.size() > 0) {
                            DTO.user.UserDTO userDTO = users.get(0);
                            predicates.add(criteriaBuilder.equal(root.get("userId").as(String.class), userDTO.getId()));
                        }
                    } else {
                        Predicate p = criteriaBuilder.like(root.get("plateNum").as(String.class), "%" + keyword + "%");
                        predicates.add(p);
                    }
                }
            }
            //已支付订单
            predicates.add(criteriaBuilder.equal(root.get("status"), 1));
            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        }, pageable);
        List<ParkingRecord> content = paged.getContent();
        List<String> userIds = content.stream().filter(distinctByKey(ParkingRecord::getUserId)).map(ParkingRecord::getUserId).collect(Collectors.toList());
        IdDTO idDTO = new IdDTO();
        idDTO.setForeignKeyIds(userIds);
        System.out.println(userIds);
        UserInfoDTO userInfoDTO = restTemplate.postForObject("http://QUANQUAN-USER/user/query_by_id_list", idDTO, UserInfoDTO.class);
        assert userInfoDTO != null;
        List<UserDTO> userDTOS = userInfoDTO.getUserDTOS();

        List<ParkingRecord> payNotifies = paged.getContent();
        List<KetopParkingRecordDTO> payNotifyDTOS = new LinkedList<>();
        for (ParkingRecord parkingRecord : payNotifies) {
            KetopParkingRecordDTO parkingRecordDTO = new KetopParkingRecordDTO();
            BeanUtils.copyProperties(parkingRecord, parkingRecordDTO);

            for (DTO.user.UserDTO userDTO : userDTOS) {
                if (parkingRecordDTO.getUserId().equals(userDTO.getId())) {
                    parkingRecordDTO.setNickName(userDTO.getMemberName());
                    parkingRecordDTO.setPhone(userDTO.getPhone());
                    parkingRecordDTO.setMemberCard(userDTO.getMemberCardNum());
                }
            }
            payNotifyDTOS.add(parkingRecordDTO);
        }

        PageDTO<KetopParkingRecordDTO> dto = new PageDTO<>();
        dto.setTotal(paged.getTotalElements());
        dto.setList(payNotifyDTOS);
        dto.setPage(page);
        dto.setPageSize(size);
        dto.setKeyword(requestBody.getKeyword());
        dto.setTotalPage(paged.getTotalPages());
        dto.setFromDate(fromDate);
        dto.setToDate(toDate);
        System.out.println(dto);
        return dto;
    }

    private static <T> java.util.function.Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }

    /**
     * 账单减免计费接口(点击使用积分，账单减免计费接口)
     *
     * @param request
     * @return
     */
    public Map<String, Object> useUserDiscount(PayParkingFeeRequest request) {
        Map<String, Object> map = new HashMap<>();
        UserRequestBody userRequestBody = new UserRequestBody();
        //通过openid查找用户
        userRequestBody.setUserId(request.getUserId());
        String postJson1 = Request.postJson(userUrl + "/user/qurey_by_user_id", userRequestBody);
        JSONObject jsonObject1 = JSON.parseObject(postJson1);
        if (null == jsonObject1) {
            map.put("msg", "用户系统异常");
            return map;
        }
        Integer resCode1 = jsonObject1.getInteger("resCode");
        UserDTO data1;
        if (0 != resCode1) {
            map.put("msg", "未查询到该用户");
            return map;
        }
        Date date = new Date();
        System.out.println(date);
        Integer money;
        UserDisCount userDiscountFee1 = userDisCountService.userDisCountFront();
        if (userDiscountFee1 != null) {
            money = userDiscountFee1.getUserFreeValue() * 100;
        } else {
            map.put("msg", "未查询到对应会员优免活动");
            return map;
        }
        boolean b = useInteagralToday(request.getUserId());
        if (b) {
            // 今日已使用会员权益进行车费抵扣
            map.put("msg", "今日已使用");
            return map;
        }
        //根据停车发放券状态判断是否核销

        // 配置金额抵扣
        request.setDisType(3);
        request.setType(0);
        request.setFreeMoney(money);
        request.setFreeTime(0);
        //封装抵扣细节
        FreeDetail freeDetail = new FreeDetail();
        freeDetail.setCode(request.getUserId());
        freeDetail.setMoney(money);
        freeDetail.setTime(0);
        freeDetail.setType(2);
        List<FreeDetail> freeDetails = new LinkedList<>();
        freeDetails.add(freeDetail);
        request.setFreeDetail(freeDetails);

        PaymentRechargeDTO paymentRechargeDTO = getPaymentRecharge(request);
        map.put("msg", "SUCCESS");
        map.put("orderNo", paymentRechargeDTO.getOrderNo());
        DecimalFormat df = new DecimalFormat("0.00");
        double fee = paymentRechargeDTO.getPayable().doubleValue();
        String feeYuan = df.format(fee / 100);
        map.put("payable", feeYuan);
        return map;

    }

    /**
     * 确认使用积分
     *
     * @param request
     * @return
     */
    public String sureUseUserDiscount(PayParkingFeeRequest request) {
        UserRequestBody userRequestBody = new UserRequestBody();
        //通过openid查找用户
        userRequestBody.setUserId(request.getUserId());
        String postJson1 = Request.postJson(userUrl + "/user/qurey_by_user_id", userRequestBody);
        JSONObject jsonObject1 = JSON.parseObject(postJson1);
        if (null == jsonObject1) {
            return "用户系统异常";
        }
        Integer resCode1 = jsonObject1.getInteger("resCode");
        if (0 != resCode1) {
            return "未查询到该用户";
        }
        Date date = new Date();
        System.out.println(date);
        int money;
        // 使用会员停车权益
        // TODO 查询到对应的会员抵扣金额
        UserDisCount userDiscountFee1 = userDisCountService.userDisCountFront();
        if (userDiscountFee1 != null) {
            money = userDiscountFee1.getUserFreeValue() * 100;
        } else {
            return "未查询到对应会员优免活动";
        }
        boolean b = useInteagralToday(request.getUserId());
        if (b) {
            // 今日已使用会员权益进行车费抵扣
            return "今日已使用";
        }
        //根据停车发放券状态判断是否核销
        // 配置金额抵扣
        request.setDisType(3);
        request.setType(1);
        request.setFreeMoney(money);
        request.setFreeTime(0);
        //封装抵扣细节
        FreeDetail freeDetail = new FreeDetail();
        freeDetail.setCode(request.getUserId());
        freeDetail.setMoney(money);
        freeDetail.setTime(0);
        freeDetail.setType(2);
        List<FreeDetail> freeDetails = new LinkedList<>();
        freeDetails.add(freeDetail);
        request.setFreeDetail(freeDetails);
        ParkingRecord parkingRecord = payParkingFee(request);
        if (parkingRecord != null) {
            return "SUCCESS";
        } else {
            return "抵扣失败";
        }
    }

    /**
     * 查询用户今天是否使用了会员优惠
     *
     * @param usreId
     * @return
     */
    public boolean useInteagralToday(String usreId) {
        List<ParkingRecord> byUserIdAndTime = parkingRecordRepository.findByUserIdAndTime(usreId);
        // 如果使用过返回true,未使用返回false
        return byUserIdAndTime.size() > 0;
    }


    /**
     * 同步停车账单
     *
     * @return
     * @see [类、类#方法、类#成员]
     */
    public boolean getPaymentRechargeOld(PayParkingFeeRequest request) {
        String apiName = "pay/GetPaymentRecharge";
        String result = null;
        try {
            result = BaseApi.doApi(request, apiName);
            JSONArray list = JSONObject.parseArray(result);
            if (list.size() > 0) {
                boolean flag = payParkingFeeOld(request);
                if (flag) {

                    //发送任务队列，完成签到任务

                    Map<String, Object> properties = new HashMap<>();
                    properties.put("userId", request.getUserId());
                    properties.put("taskType", "parking");

                    //将计算结果放到MQ队列去补充明细的余额
                    String msg = "补全积分明细余额";
                    String exchange = "task.exchange";
                    String routingKey = "task.sign";
                    rabbitSender.sendMessageToMQ(msg, properties, exchange, routingKey);

                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } catch (RequestException e) {
            e.printStackTrace();
        } catch (EncodeException e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 同步停车账单
     *
     * @return
     * @see [类、类#方法、类#成员]
     */
    public boolean payParkingFeeOld(PayParkingFeeRequest request) {
        Integer payType = 24;
        Integer payMethod = 4;
        String apiName = "pay/PayParkingFee";
        request.setPayType(payType);
        request.setPayMethod(payMethod);
        request.setDiscount(0);
        String result = null;
        try {
            result = BaseApi.doApi(request, apiName);
            JSONObject jo = JSONObject.parseObject(result);
            if (jo.containsKey("parkingTime")) {
                Integer parkingTime = jo.getInteger("parkingTime");
                //拿到科拓的返回值，更新我们的停车支付状态为已支付
                List<ParkingRecord> parkingRecords = parkingRecordRepository.findByOrderNo(request.getOrderNo());
                if (parkingRecords.size() > 0) {
                    ParkingRecord parkingRecord = parkingRecords.get(0);
                    parkingRecord.setParkingTime(parkingTime);
                    parkingRecord.setTransactionId(request.getTransactionId());
                    // 更新实际支付金额
                    /*if (parkingRecord.getFee() > parkingRecord.getTotalFreeFee()) {
                        parkingRecord.setFee(parkingRecord.getFee() - parkingRecord.getTotalFreeFee());
                    } else {
                        parkingRecord.setFee(0);
                    }*/
                    parkingRecord.setStatus(1);
                    parkingRecord.setUpdateTime(DateUtils.currentDate());
                    parkingRecordRepository.saveAndFlush(parkingRecord);
                    return true;
                } else {
                    return false;
                }
               /* return JSON.parseObject(result, new TypeReference<BaseResponse<PayParkingFeeResponse>>() {
                });*/

            }
        } catch (RequestException e) {
            e.printStackTrace();
        } catch (EncodeException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 查询停车费用(保存订单)
     *
     * @return
     * @see [类、类#方法、类#成员]
     */
    public List<ParkingRecord> queryParkingFeeAndCreateOrderOld(UserCarKetopRequest userCarKetopRequest) {
        String apiName = "pay/GetParkingPaymentInfo";
        QueryParkingFeeRequest request = new QueryParkingFeeRequest();
        request.setPlateNo(userCarKetopRequest.getPlateNum());
        String result = null;
        List<ParkingRecord> parkingRecords = new LinkedList<>();
        try {
            result = BaseApi.doApi(request, apiName);
            JSONArray list = JSONObject.parseArray(result);
            for (int i = 0; i < list.size(); i++) {
                ParkingFeeResponse data = list.getObject(i, ParkingFeeResponse.class);
                ParkingRecord parkingRecord = new ParkingRecord();
                parkingRecord.setId(UUIDGenerator.getUUID());
                parkingRecord.setCreateTime(DateUtils.currentDate());
                parkingRecord.setUpdateTime(DateUtils.currentDate());
                parkingRecord.setOrderNo(data.getOrderNo());
                parkingRecord.setInTime(data.getEntryTime());
                parkingRecord.setPayTime(data.getPayTime());
                parkingRecord.setParkingTime(data.getElapsedTime());
                parkingRecord.setImgName(data.getImgName());
                //用户支付的抵扣积分
                parkingRecord.setIntegral(userCarKetopRequest.getIntegral());
                parkingRecord.setUserDiscount(userCarKetopRequest.getUserDiscount());
                //积分抵扣金额
                Integer totalFreeFee;
                if (userCarKetopRequest.getIntegral() == null || userCarKetopRequest.getIntegral() <= 0) {
                    totalFreeFee = 0;
                } else {
                    totalFreeFee = (userCarKetopRequest.getIntegral() / 20) * 50;
                }
                Integer userDiscountFee;
                // 使用会员停车权益
                if (userCarKetopRequest.getUserDiscount() != null && userCarKetopRequest.getUserDiscount() == 1) {
                    boolean b = useInteagralToday(userCarKetopRequest.getUserId());
                    if (b) {
                        // 今日已使用会员权益进行车费抵扣
                        return null;
                    }
                    // TODO 查询到对应的会员抵扣金额
                    UserDisCount userDiscountFee1 = userDisCountService.userDisCountFront();
                    if (userDiscountFee1 != null) {
                        userDiscountFee = userDiscountFee1.getUserFreeValue() * 100;
                        totalFreeFee = totalFreeFee + userDiscountFee;
                    }
                }
                parkingRecord.setTotalFee(data.getPayable());
                parkingRecord.setTotalFreeFee(totalFreeFee);
                if (data.getPayable() < totalFreeFee) {
                    parkingRecord.setFee(0);
                } else {
                    parkingRecord.setFee(data.getPayable() - totalFreeFee);
                }
                parkingRecord.setDelayTime(data.getDelayTime());
                parkingRecord.setUserId(userCarKetopRequest.getUserId());
                parkingRecord.setPlateNum(userCarKetopRequest.getPlateNum());
                parkingRecord.setStatus(0);
                parkingRecordRepository.saveAndFlush(parkingRecord);
                parkingRecords.add(parkingRecord);
            }
            return parkingRecords;
        } catch (RequestException e) {
            e.printStackTrace();
        } catch (EncodeException e) {
            e.printStackTrace();
        }
        return null;
    }


}
